<template>
    <div style="height: 100%; width: 100%">
        <div id="container" :style="styleObj" v-loading="doLoading"></div>

        <div class="configBtn">
            <el-button @click="showConfig">
                {{$t('maps.offlineBaiduMap.config')}}
            </el-button>
        </div>

        <div class="mapsConfigCss">
            <el-form>
                <el-form-item :label="$t('maps.offlineBaiduMap.position')">
                    <select v-model="prov">
                        <option v-for="option in coordinateArr" :value="option.name">
                            {{ option.name }}
                        </option>
                    </select>
                    <select v-model="city"
                            v-if="coordinateArr[prov].subNodesCount">
                        <option :value="$t('maps.offlineBaiduMap.pleaseSelect')">{{$t('maps.offlineBaiduMap.pleaseSelect')}}</option>
                        <option v-for="option in coordinateArr[prov].subNodes" :value="option.name">
                            {{ option.name }}
                        </option>
                    </select>
                    <select v-model="district"
                            v-if="coordinateArr[prov].subNodesCount &&
                    coordinateArr[prov].subNodes[city] &&
                    coordinateArr[prov].subNodes[city].subNodesCount">
                        <option :value="$t('maps.offlineBaiduMap.pleaseSelect')">{{$t('maps.offlineBaiduMap.pleaseSelect')}}</option>
                        <option v-for="option in coordinateArr[prov].subNodes[city].subNodes" :value="option.name">
                            {{ option.name }}
                        </option>
                    </select>
                </el-form-item>
            </el-form>
        </div>

        <el-dialog
                :title="$t('maps.offlineBaiduMap.title')"
                :visible="isConfigShow"
                :before-close="handleClose" center width="70%">

            <el-form label-width="150px" label-position="right"
                     class="demo-form-inline" style="width: 95%">

                <el-form-item :label="$t('maps.offlineBaiduMap.center')">
                    <el-input v-model="center"></el-input>
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.zoom')">
                    <el-input v-model="zoom"></el-input>
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.downloadMaxZoom')">
                    <el-input v-model="downloadMaxZoom"></el-input>
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.styleJson')">
                    <el-input auto-complete="off" v-model="styleJson"
                              clearable type="textarea" resize="none"
                              :rows="10"
                              :autosize="{minRows: 10, maxRows: 10 }"
                              style="margin-top: 10px;"></el-input>
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.node')">
                    <p v-html="$t('maps.offlineBaiduMap.nodeTip')" style="line-height: 20px;"></p>
                </el-form-item>

                <el-form-item>
                    <el-button @click="handleConfig">{{$t('common.btn_ok')}}</el-button>
                    <el-button @click="handleClose">{{$t('common.btn_cancel')}}</el-button>
                    <el-button @click="showDownload">
                        {{$t('maps.offlineBaiduMap.createDownloadTask')}}
                    </el-button>
                </el-form-item>
            </el-form>
        </el-dialog>

        <el-dialog
                :title="$t('maps.offlineBaiduMap.titleDownload')"
                :visible="isDownloadShow"
                :before-close="handleDownloadClose" center>

            <el-form label-width="150px" label-position="right"
                     class="demo-form-inline" style="width: 95%">

                <el-form-item :label="$t('maps.offlineBaiduMap.taskName')">
                    <el-input v-model="taskName"></el-input>
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.center')">
                    {{center}}
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.zoom')">
                    {{zoom}}
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.downloadMaxZoom')">
                    {{downloadMaxZoom}}
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.zoomdatadesc')">
                    <el-table :data="zoomdatadesc" height="300">
                        <el-table-column :label="$t('maps.offlineBaiduMap.zoomLevel')"
                                         prop="zoomLevel" width="60"></el-table-column>
                        <el-table-column :label="$t('maps.offlineBaiduMap.imgCount')"
                                         prop="totalCount" width="200"></el-table-column>
                        <el-table-column :label="$t('maps.offlineBaiduMap.singleImgSize')"
                                         prop="singleImgSize" width="120"></el-table-column>
                        <el-table-column :label="$t('maps.offlineBaiduMap.totalSize')"
                                         prop="totalSize">
                            <template slot-scope="scope">
                                {{scope.row.totalSize + ' (' +scope.row.totalSizeUnit + ')'}}
                            </template>
                        </el-table-column>
                    </el-table>
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.allDataSize')">
                    {{allParams.totalSize + ' (' +allParams.totalSizeUnit + ')'}}
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.url')">
                    {{url}}
                </el-form-item>

                <el-form-item :label="$t('maps.offlineBaiduMap.downloadDir')">
                    <el-input v-model="downloadDir"></el-input>
                </el-form-item>

                <el-form-item>
                    <el-button @click="handleDownload">{{$t('maps.offlineBaiduMap.addToDownloadTask')}}</el-button>
                    <el-button @click="handleDownloadClose">{{$t('common.btn_cancel')}}</el-button>
                </el-form-item>

            </el-form>
        </el-dialog>
    </div>
</template>

<script>
    const ZOOM_CHINA = 6;
    const ZOOM_PROV = 9;
    const ZOOM_CITY = 12;
    const ZOOM_DISTRICT = 15;

    import 'echarts/map/js/china.js'
    import 'echarts/map/js/world.js'
    import 'echarts/extension/bmap/bmap'

    import {deepCopyArray, deepCopyObj} from '@/utils/objectUtils'
    import {mapOption} from './mapOption'
    import {findAllTiles_2} from './getDownloadUrls'

    import {CITY_DATA} from '@/resource/predefineds/maps/cityData'

    import {DBInsert, DBFind, DBCount} from '@/api/NEDB/nedbApi'
    import fs from 'fs'
    import path from 'path'

    export default {
        name: 'offlineBaiduMap',

        watch:{
            prov: function(){
                this.city = this.$t('maps.offlineBaiduMap.pleaseSelect');
                this.district = this.$t('maps.offlineBaiduMap.pleaseSelect');

                const option = this.myChart.getOption();
                option.bmap[0].center = this.coordinateArr[this.prov].coordinate;
                option.bmap[0].zoom = ZOOM_PROV;
                if(this.prov == this.$t('maps.offlineBaiduMap.china')) {
                    option.bmap[0].zoom = ZOOM_CHINA;
                }

                this.center = option.bmap[0].center.join(',');
                this.zoom = option.bmap[0].zoom;

                if (option && typeof option === "object") {
                    this.myChart.setOption(option, true);
                }
            },
            city: function(){
                this.district = this.$t('maps.offlineBaiduMap.pleaseSelect');

                if(this.city === this.$t('maps.offlineBaiduMap.pleaseSelect')){
                    return;
                }

                const option = this.myChart.getOption();
                option.bmap[0].center = this.coordinateArr[this.prov].subNodes[this.city].coordinate;
                option.bmap[0].zoom = ZOOM_CITY;

                this.center = option.bmap[0].center.join(',');
                this.zoom = option.bmap[0].zoom;

                if (option && typeof option === "object") {
                    this.myChart.setOption(option, true);
                }
            },
            district: function(){
                if(this.district === this.$t('maps.offlineBaiduMap.pleaseSelect')){
                    return;
                }

                const option = this.myChart.getOption();
                option.bmap[0].center = this.coordinateArr[this.prov].subNodes[this.city].subNodes[this.district].coordinate;
                option.bmap[0].zoom = ZOOM_DISTRICT;

                this.center = option.bmap[0].center.join(',');
                this.zoom = option.bmap[0].zoom;

                if (option && typeof option === "object") {
                    this.myChart.setOption(option, true);
                }
            }
        },

        data() {
            return {
                msg: '地图离线下载工具',

                styleObj: {
                    width: '100%',
                    height: '100%',
                    paddingTop: 0
                },

                loading: null,

                myChart: null,
                default_center: [104.937004,35.51392],

                isConfigShow: false,
                isDownloadShow: false,

                center: '',
                zoom: 10,
                // downloadMinZoom: 10,
                downloadMaxZoom: 18,
                styleJson: '',

                zoomdatadesc: [],
                url: '',
                allParams: {},
                styleStr: '',

                coordinate: [],
                prov: this.$t('maps.offlineBaiduMap.china'),
                city: this.$t('maps.offlineBaiduMap.pleaseSelect'),
                district: this.$t('maps.offlineBaiduMap.pleaseSelect'),
                coordinateArr: {},
                downloadDir: '',
                taskName: '',

                doLoading: true
            }
        },

        created: function () {
            this.createCityData();
            this.downloadDir = this.$store.getters.userDownloadPath;
        },

        beforeRouteUpdate (to, from, next) {
            // 因为点击当前页面触发beforeRouteUpdate方法会触发两次
            // 第一次为两个时间都不为空，第二次为from的t不为空
            //
            // 从其他页面切换过来，to的t为空，from的t不为空
            //
            // 只有当前页面点击的才能触发beforeRouteUpdate方法

            if(to.path == from.path && typeof(to.query.t)!='undefined' && typeof(from.query.t)!='undefined'){
                // 两个时间都不是空的时候，表示是当前页面点击进入的
                // 设置beforeRouteUpdate的状态为允许触发
                this.$store.dispatch('setBeforeRouteUpdateActive', true);
                return;
            }

            // 增加判断：第一次切换进入页面时，to的t不为空，form的t为空；且this.$store.getters.beforeRouteUpdateActive为false
            // 重新进入页面：只有to的t为空，且设置允许触发的，才能触发，触发后就设置为false
            if(to.path == from.path && (
                (typeof(to.query.t)=='undefined' && this.$store.getters.beforeRouteUpdateActive)
                || (typeof(to.query.t)!='undefined' && typeof(from.query.t)=='undefined' && !this.$store.getters.beforeRouteUpdateActive)
            )){
                this.$store.dispatch('setBeforeRouteUpdateActive', false);
                this.initEchart();
            }
        },

        methods: {
            initEchart() {
                this.myChart = this.$echarts.init(document.getElementById("container"));

                const option = deepCopyArray(mapOption);

                option.bmap.center = this.default_center;

                option.series[0].symbolSize = function (val) {
                    return val[2] / 10;
                }

                if (option && typeof option === "object") {
                    this.myChart.setOption(option, true);
                }

                this.center = option.bmap.center.join(',');
                this.zoom = option.bmap.zoom;
                this.styleJson = JSON.stringify(option.bmap.mapStyle.styleJson);

                this.doLoading = false;
            },

            resetSize() {
                try {
                    let fullHeight = document.getElementById("loadPageDiv").offsetHeight;
                    // let dialogHeaderTitleHeight = document.getElementById("dialogHeaderTitle").offsetHeight;
                    // this.styleObj.height = fullHeight - dialogHeaderTitleHeight + 'px';
                    this.styleObj.height = fullHeight + 'px';
                } catch (e) {
                }

                let that = this;
                if (that && !that._isDestroyed) {
                    setTimeout(() => {
                        if (that && !that._isDestroyed) {
                            that.resetSize();
                        }
                    }, 500);
                }
            },

            showConfig() {
                this.isConfigShow = true;
            },

            handleClose() {
                this.isConfigShow = false;
            },

            checkIsNum(str) {
                if (str == '' || str == null || typeof str == 'undefined' || isNaN(str)) {
                    return false;
                }
                return true;
            },

            handleConfig() {
                if (this.center.indexOf(',') < 0) {
                    console.log('1' + '--' + this.center);
                    this.$message.error(this.$t('maps.offlineBaiduMap.centerError'));
                    return false;
                }
                let center = this.center.split(',');
                if (!this.checkIsNum(center[0]) || !this.checkIsNum(center[1])) {
                    console.log('2' + '--' + this.center);
                    this.$message.error(this.$t('maps.offlineBaiduMap.centerError'));
                    return false;
                }

                if (!this.checkIsNum(this.zoom)) {
                    this.$message.error(this.$t('maps.offlineBaiduMap.zoomError'));
                    return false;
                }

                if (!this.checkIsNum(this.downloadMaxZoom)) {
                    this.$message.error(this.$t('maps.offlineBaiduMap.downloadMaxZoomError'));
                    return false;
                }

                this.downloadMaxZoom = parseInt(this.downloadMaxZoom);
                this.zoom = parseInt(this.zoom);

                if (this.downloadMaxZoom > 18) {
                    this.$message.error(this.$t('maps.offlineBaiduMap.downloadMaxZoomError'));
                    return false;
                }

                if (this.downloadMaxZoom < this.zoom) {
                    this.$message.error(this.$t('maps.offlineBaiduMap.downloadZoomError'));
                    return false;
                }

                try {
                    let styleJson = JSON.parse(this.styleJson);
                } catch (e) {
                    this.$message.error(this.$t('maps.offlineBaiduMap.styleJsonError'));
                    return false;
                }

                this.resetOptionWithConfig();

                this.isConfigShow = false;

                return true;
            },

            resetOptionWithConfig() {
                let center = this.center.split(',');
                const styleJson = JSON.parse(this.styleJson);
                const option = this.myChart.getOption();

                option.bmap[0].center = center;
                option.bmap[0].zoom = this.zoom;
                option.bmap[0].mapStyle.styleJson = styleJson;

                if (option && typeof option === "object") {
                    this.myChart.setOption(option, true);
                }
            },

            showDownload() {
                if(this.handleConfig()){
                    this.openFullScreen('common.isloading');
                    setTimeout(()=>{
                        this.showDownload2();
                    },200);
                }
            },
            showDownload2(){
                // this.resetOptionWithConfig();
                const map = this.myChart.getModel().getComponent('bmap').getBMap();
                const data = findAllTiles_2(map, this.zoom, this.downloadMaxZoom);
                this.styleStr = map.D.w_.styleStr;
                this.zoomdatadesc = data[0];
                this.allParams = data[1];

                this.loading.close();
                this.isDownloadShow = true;
            },
            handleDownloadClose() {
                this.isDownloadShow = false;
            },

            handleDownload() {
                if(this.downloadDir == ''){
                    this.$message.error(this.$t('maps.offlineBaiduMap.needDownloadDir'));
                    return;
                }
                if(this.taskName==''){
                    this.$message.error(this.$t('maps.offlineBaiduMap.taskNameError'));
                    return;
                }

                // 没有下载目录的时候，自行创建目录
                if (!fs.existsSync(this.downloadDir)) {
                    this.mkdirSync(this.downloadDir);
                }

                this.openFullScreen('maps.offlineBaiduMap.loadingDownload');
                // 添加下载任务
                this.createDownloadTask();
                // 跳转下载页面

                this.loading.close();
                this.isDownloadShow = false;
            },
            mkdirSync(dirname) {
                if (fs.existsSync(dirname)) {
                    return true;
                } else {
                    if (this.mkdirSync(path.dirname(dirname))) {
                        fs.mkdirSync(dirname);
                        return true;
                    }
                }
                return false
            },

            openFullScreen(str) {
                this.loading = this.$loading({
                    lock: true,
                    text: this.$t(str),
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                });
            },

            createDownloadTask() {
                // this.$message.error(this.$t('maps.offlineBaiduMap.addTasksError'));

                // 1、创建新的下载任务
                // 任务名称
                let timelong = new Date().getTime();
                let name = this.taskName;
                let taskId = timelong;
                let dataSize = this.allParams.totalSize;
                let dataSizeUnit = this.allParams.totalSizeUnit;
                let dataTotalCount = this.allParams.totalCount;
                let taskAddTime = timelong;

                let newTask = {
                    taskId: taskId,
                    taskName: name,
                    taskAddTime: taskAddTime,
                    taskStatus: 'stop',
                    dataSize: dataSize,
                    dataSizeUnit: dataSizeUnit,
                    dataTotalCount: dataTotalCount,
                    downloadDir: this.downloadDir,
                    progress: 0,
                };

                // 2、将下载任务写入数据库
                DBInsert('DOWNLOADTASKCONF_DB', newTask, (data)=>{
                    console.log(data);
                });

                // 3、创建下载任务具体数据文件
                let taskParentId = taskId;
                const taskDescData = [];
                const taskIndex = 0;
                let hearder = 'http://api0.map.bdimg.com/customimage/tile?';
                let urlMiddel = '&udt=20181025&scale=1&ak=';
                let styleJson = JSON.parse(this.styleJson);

                let params = {
                    taskParentId: taskParentId,
                    index: taskIndex,
                    hearder: hearder,
                    urlMiddel: urlMiddel,
                    styleJson: this.styleStr,
                    zoomdatadesc: this.zoomdatadesc,
                    totalCount: this.allParams.totalCount,
                    currentDownload: {}
                };

                // 4、将下载任务具体信息写入数据库
                DBInsert('DOWNLOADTASKS_DB', params, (data)=>{
                    console.log(data);
                });

                this.$message.success(this.$t('maps.offlineBaiduMap.addTasksSuccess'));
            },

            createCityData(){
                var data = {};

                for(var i in CITY_DATA){
                    let tempV = CITY_DATA[i];
                    let tempKArr = i.split('-');
                    let n = tempKArr.length - 1;
                    if(n==0){
                        data[i] = {
                            name: i,
                            coordinate: tempV,
                            subNodes: {},
                            subNodesCount: 0
                        };
                    }
                    else if(n==1){
                        data[tempKArr[0]].subNodesCount = data[tempKArr[0]].subNodesCount + 1;
                        data[tempKArr[0]].subNodes[tempKArr[1]] = {
                            name: tempKArr[1],
                            coordinate: tempV,
                            subNodes: {},
                            subNodesCount: 0
                        }
                    }
                    else if(n==2){
                        data[tempKArr[0]].subNodes[tempKArr[1]].subNodesCount =
                            data[tempKArr[0]].subNodes[tempKArr[1]].subNodesCount + 1;
                        data[tempKArr[0]].subNodes[tempKArr[1]].subNodes[tempKArr[2]] = {
                            name: tempKArr[2],
                            coordinate: tempV
                        }
                    }
                }

                this.coordinateArr = data;
            },

            doSelectMapsPosition(){
                let zoom = ZOOM_PROV;
                let center = this.coordinateArr[this.prov].coordinate;
                if(this.prov == this.$t('maps.china')) {
                    zoom = ZOOM_CHINA;
                }

                if(this.coordinateArr[this.prov].subNodes[this.city]){
                    zoom = ZOOM_CITY;
                    center = this.coordinateArr[this.prov].subNodes[this.city].coordinate;

                    if(this.coordinateArr[this.prov].subNodes[this.city].subNodes[this.district]){
                        zoom = ZOOM_DISTRICT;
                        center = this.coordinateArr[this.prov].subNodes[this.city].
                            subNodes[this.district].coordinate;
                    }
                }

                let params = {
                    center : center.join(","),
                    zoom : zoom,
                    prov : this.prov,
                    city : this.city,
                    district : this.district
                };

                console.log(params);

            },

        },

        mounted: function () {
            let that = this;
            if (that && !that._isDestroyed) {
                this.resetSize();

                setTimeout(()=>{
                    that.initEchart();
                }, 3000);
            }
        }
    }
</script>

<style scoped>
    .configBtn {
        position: absolute;
        top: 10px;
        left: 10px;
        font-weight: 800;
    }

    /** 隐藏左下角的百度标识 */
    >>> .anchorBL {
        display: none
    }

    >>> .el-form-item {
        margin-bottom: 5px;
    }

    .mapsConfigCss{
        padding-left: 10px;
        position: absolute;
        left: 10px;
        bottom: 10px;
        width: 550px;
        height: 40px;
        color: #CCCCCC;
        background: rgba(0, 0, 0, 0.67);
    }
</style>
